home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 February: Tool Chest / Apple Developer CD Series Tool Chest February 1996 (Apple Computer)(1996).iso / Sample Code / AppsToGo / DTS.Draw / TRectObj.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-09-22  |  17.2 KB  |  566 lines  |  [TEXT/MPS ]

  1. /*
  2. ** Apple Macintosh Developer Technical Support
  3. **
  4. ** File:        TRectObj.c
  5. ** Written by:    Eric Soldan
  6. **
  7. ** Copyright © 1992-1993 Apple Computer, Inc.
  8. ** All rights reserved.
  9. */
  10.  
  11. /* You may incorporate this sample code into your applications without
  12. ** restriction, though the sample code has been provided "AS IS" and the
  13. ** responsibility for its operation is 100% yours.  However, what you are
  14. ** not permitted to do is to redistribute the source as "DSC Sample Code"
  15. ** after having made changes. If you're going to re-distribute the source,
  16. ** we require that you make it clear in the source that the code was
  17. ** descended from Apple Sample Code, but that you've made changes. */
  18.  
  19. /* See the files "=How to write your app" and "=Using TreeObj.c" for information
  20. ** on this function. */
  21.  
  22. /* This file implements the messages for the rect object. */
  23.  
  24.  
  25.  
  26. /*****************************************************************************/
  27.  
  28.  
  29.  
  30. #include "App.h"            /* Get the application includes/typedefs, etc.    */
  31. #include "App.protos.h"        /* Get the prototypes for the application.        */
  32.  
  33. #ifndef __OSEVENTS__
  34. #include <OSEvents.h>
  35. #endif
  36.  
  37. #ifndef __OSUTILS__
  38. #include <OSUtils.h>
  39. #endif
  40.  
  41. #ifndef __QUICKDRAW__
  42. #include <Quickdraw.h>
  43. #endif
  44.  
  45. #ifndef __TREEOBJ2__
  46. #include "TreeObj2.h"
  47. #endif
  48.  
  49. #ifndef __UTILITIES__
  50. #include "Utilities.h"
  51. #endif
  52.  
  53.  
  54.  
  55. /*****************************************************************************/
  56.  
  57.  
  58.  
  59. RGBColor    gBorderColor  = {0, 0, 0};
  60. RGBColor    gContentColor = {0xFFFF, 0xFFFF, 0xFFFF};
  61. short        gPenHeight = 1;
  62. short        gPenWidth  = 1;
  63.  
  64.  
  65.  
  66. /*****************************************************************************/
  67.  
  68.  
  69.  
  70. static RectObjPeek    *gMWERKSDebug;
  71.     /* For Metroweks debugging of AppsToGo "objects", you need an instance of the
  72.     ** same type you wish to view it in the debugger.  Now we have an instance. */
  73.  
  74.  
  75.  
  76. /*****************************************************************************/
  77. /*****************************************************************************/
  78.  
  79. #ifdef applec
  80. #pragma segment DTSDrawSeg2
  81. #endif
  82.  
  83. /*****************************************************************************/
  84. /*****************************************************************************/
  85.  
  86.  
  87.  
  88. long    TRectObj(TreeObjHndl hndl, short message, long data)
  89. {
  90.     TreeObjHndl    root, shndl;
  91.     Rect        rct, oldRct, *rptr, grabber;
  92.     short        hit, fileRefNum, dx1, dx2, dy1, dy2, h, v, ptype;
  93.     short        fv, fh, flip, noDraw, w;
  94.     Point        where, begMouse, curMouse, offset;
  95.     Boolean        selected;
  96.     EventRecord    option;
  97.     ClickInfo    *click;
  98.     RgnHandle    rgn, accumRgn;
  99.     OSErr        err;
  100.     RGBColor    rgb, rgb2;
  101. #if VH_VERSION
  102.     char        *cptr;
  103. #endif
  104.  
  105.     switch (message) {
  106.         case INITMESSAGE:
  107.                 /* This is called either with a sub-message of CREATEINIT or WINDOWINIT.
  108.                 ** The sub-message CREATEINIT is sent in when the object is initially created.
  109.                 ** The sub-message WINDOWINIT is sent in when the object belongs to a document
  110.                 ** that was just assigned to a window.  Note that the object could be created
  111.                 ** into a document that already has a window.  In this case, only the
  112.                 ** CREATEINIT sub-message will be received.  It is the object's responsibility
  113.                 ** to determine if the document has a window when CREATEINIT is called.
  114.                 ** An additional possible sub-message is NOWINDOWINIT.  In this case, the
  115.                 ** document is being disconnected from a window, and therefore objects have
  116.                 ** to convert back to their non-window state.  Both the WINDOWINIT and
  117.                 ** NOWINDOWINIT sub-messages would be application-specific, and sending
  118.                 ** the sub-messages to the objects would be the application's responsibility. */
  119.             mDerefCommon(hndl)->penHeight    = gPenHeight;
  120.             mDerefCommon(hndl)->penWidth     = gPenWidth;
  121.             mDerefCommon(hndl)->borderColor  = gBorderColor;
  122.             mDerefCommon(hndl)->content      = true;
  123.             mDerefCommon(hndl)->contentColor = gContentColor;
  124.             break;
  125.  
  126.         case FREEMESSAGE:
  127.             if (mDerefCommon(hndl)->selected) {
  128.                 root = GetRootHndl(hndl);
  129.                 if ((*root)->type == ROOTOBJ)
  130.                     mDerefRoot(root)->numSelected--;
  131.                         /* Here the root object can be either the document root
  132.                         ** or the undo root.  The FREEOBJMESSAGE is due to the
  133.                         ** object being disposed of.  It may be being disposed of
  134.                         ** from either the document or undo side.  If it is being
  135.                         ** disposed of out of the undo side, we don't care about
  136.                         ** the selection status.  If it is being disposed of out
  137.                         ** of the document side, then we do care, as we will have
  138.                         ** one less selected object.  The numSelected count needs
  139.                         ** to reflect this. */
  140.             }
  141.             break;
  142.  
  143.         case COPYMESSAGE:
  144.                 /* CopyOneChild was called (indirectly) and an object has been
  145.                 ** cloned.  At this point the data area has already been copied.
  146.                 ** If the data area holds references to other handles, these
  147.                 ** handles need to be copied so that the object has its own copies.
  148.                 ** Since the data was copied from the original child, the fields
  149.                 ** holding references to handles actually contain the same reference
  150.                 ** that the original child contains.  To create unique handles for
  151.                 ** the copy, this object should pass itself an INITOBJMESSAGE to
  152.                 ** initially create unique handles for the copy.
  153.                 ** The data parameter for this message is the handle of the object
  154.                 ** that was copied.  It is possible that the copy won't be an exact
  155.                 ** copy, and that there should be some differences between the
  156.                 ** original and the copy.  By having a reference to the original,
  157.                 ** these situations can be resolved. */
  158.             break;
  159.  
  160.         case UNDOMESSAGE:
  161.             root  = GetRootHndl(hndl);
  162.             if ((*root)->type == ROOTOBJ) {
  163.                 ptype = (*((*hndl)->parent))->type;
  164.                 switch (data) {
  165.                     case UNDOFROMDOC:
  166.                         if (mDerefCommon(hndl)->selected == true) {
  167.                             mDerefCommon(hndl)->selected = false;
  168.                             mDerefRoot(root)->numSelected--;
  169.                         }        /* If a selected object is moving from the document into the */
  170.                         break;    /* undo, reflect this in the numSelected count in the root.  */
  171.  
  172.                     case UNDOTODOC:
  173.                         mDerefCommon(hndl)->selected = false;
  174.                         if (ptype != GROUPOBJ) {
  175.                             mDerefCommon(hndl)->selected = true;
  176.                             mDerefRoot(root)->numSelected++;
  177.                         }        /* An object moving into the document needs to be selected
  178.                                 ** so the user can see what changed.  The select status while
  179.                                 ** in the undo doesn't matter, as the user can't see what is in
  180.                                 ** the undo. */
  181.                         break;
  182.                 }
  183.             }
  184.             break;
  185.  
  186.         case CONVERTMESSAGE:
  187.                 /* This is called to convert any data that loses meaning when saved.
  188.                 ** It is called with a TOFILE or a FROMFILE sub-message.
  189.                 **
  190.                 ** For the CONVERTTOID sub-message:
  191.                 **
  192.                 ** If this object has any references to handles elsewhere in the document,
  193.                 ** these references lose meaning when saved to disk.  When the file is
  194.                 ** read in, the handle references will not coorelate to what is currently
  195.                 ** in ram.
  196.                 ** Prior to starting a file save, all of the objects in the tree are
  197.                 ** assigned sequential id numbers.  You can replace handle references
  198.                 ** with the 4-byte treeID.  To convert the handle to a treeID, just
  199.                 ** do something like the following:
  200.                 **     Hndl2ID(&DerefMyObject(hndl)->thingToConvert);
  201.                 **
  202.                 ** For the CONVERTTOHNDL sub-message:
  203.                 **
  204.                 ** Once the file is opened and completely loaded into ram, there may be
  205.                 ** objects that have references to elsewhere in the file that were stored
  206.                 ** as treeID's.  These need to be converted back to handle references.
  207.                 ** To do this, do something like the below:
  208.                 **      ID2Hndl(hndl, &DerefMyObject(hndl)->thingToConvert);
  209.                 */
  210.             break;
  211.  
  212.         case FREADMESSAGE:
  213.             fileRefNum = data;
  214.             err = ReadTreeObjData(hndl, fileRefNum);
  215.             if (!err)
  216.                 mDerefCommon(hndl)->selected = false;
  217.             return(err);
  218.             break;
  219.  
  220.         case FWRITEMESSAGE:
  221.             fileRefNum = data;
  222.             return(WriteTreeObjData(hndl, fileRefNum));
  223.             break;
  224.  
  225.         case HREADMESSAGE:
  226.             err = HReadTreeObjData(hndl, (Handle)data);
  227.             if (!err)
  228.                 mDerefCtl(hndl)->selected = false;
  229.             return(err);
  230.             break;
  231.  
  232.         case HWRITEMESSAGE:
  233.             return(HWriteTreeObjData(hndl, (Handle)data));
  234.             break;
  235.  
  236.         case HITTESTMESSAGE:
  237.             click = (ClickInfo *)data;
  238.             where = click->localEvent.where;
  239.             hit   = 0;
  240.             switch (click->message) {
  241.                 case HITTESTOBJ:
  242.                     DoTreeObjMethod(hndl, GETBBOXMESSAGE, (long)&rct);
  243.                     if (PtInRect(where, &rct)) {
  244.                         rgn = (RgnHandle)DoTreeObjMethod(hndl, GETRGNMESSAGE, 0);
  245.                         if (PtInRgn(where, rgn))
  246.                             hit = -1;
  247.                         DisposeRgn(rgn);
  248.                     }
  249.                     break;
  250.                 case HITTESTGRABBER:
  251.                     rct = mDerefCommon(hndl)->rect;
  252.                     if (mDerefCommon(hndl)->selected) {
  253.                         grabber = rct;
  254.                         InsetRect(&grabber, -4, -4);
  255.                         if (PtInRect(where, &grabber)) {
  256.                             GetMouse(&curMouse);
  257.                             for (;;) {
  258.                                 if (where.v < (rct.top + 4)) {
  259.                                     if (where.h <  (rct.left + 4) ) {
  260.                                         hit = 1;
  261.                                         flip = (VFLIPOBJ | HFLIPOBJ);
  262.                                         where.h  = rct.right;
  263.                                         where.v  = rct.bottom;
  264.                                         offset.h = rct.left - curMouse.h;
  265.                                         offset.v = rct.top  - curMouse.v;
  266.                                         break;
  267.                                     }
  268.                                     if (where.h >= (rct.right - 4)) {
  269.                                         hit = 2;
  270.                                         flip = VFLIPOBJ;
  271.                                         where.h  = rct.left;
  272.                                         where.v  = rct.bottom;
  273.                                         offset.h = rct.right - curMouse.h;
  274.                                         offset.v = rct.top   - curMouse.v;
  275.                                         break;
  276.                                     }
  277.                                 }
  278.                                 if (where.v >= (rct.bottom - 4)) {
  279.                                     if (where.h <  (rct.left + 4) ) {
  280.                                         hit = 3;
  281.                                         flip = HFLIPOBJ;
  282.                                         where.h  = rct.right;
  283.                                         where.v  = rct.top;
  284.                                         offset.h = rct.left   - curMouse.h;
  285.                                         offset.v = rct.bottom - curMouse.v;
  286.                                         break;
  287.                                     }
  288.                                     if (where.h >= (rct.right - 4)) {
  289.                                         hit = 4;
  290.                                         flip = 0;
  291.                                         where.h  = rct.left;
  292.                                         where.v  = rct.top;
  293.                                         offset.h = rct.right  - curMouse.h;
  294.                                         offset.v = rct.bottom - curMouse.v;
  295.                                         break;
  296.                                     }
  297.                                 }
  298.                                 break;
  299.                             }
  300.                         }
  301.                     }
  302.                     break;
  303.                 case CANBETARGET:
  304.                     return(false);
  305.                     break;
  306.                 case CANTAKEKEYS:
  307.                     return(false);
  308.                     break;
  309.             }
  310.             if (hit) {
  311.                 for (; (*(root = (*hndl)->parent))->type != ROOTOBJ; hndl = root) {};
  312.                     /* Group objects can not be hit directly.  Only the base
  313.                     ** objects can be hit.  However, if a base object is hit,
  314.                     ** we want to return the top-most group object that
  315.                     ** contains it.  Walk the tree up until the root object
  316.                     ** is hit.  The object below this is top-most group object,
  317.                     ** or the base object doesn't belong to a group. */
  318.                 if (click->message == HITTESTGRABBER) {
  319.                     if (mDerefRoot(root)->numSelected == 1) {
  320.                         click->localEvent.where = where;
  321.                         click->offset           = offset;
  322.                         click->oldFlip = click->newFlip = flip;
  323.                     }
  324.                     else hit = 0;
  325.                 }
  326.             }
  327.             if (!hit)
  328.                 hndl = nil;
  329.             click->grabber = hit;
  330.             return((long)hndl);
  331.             break;
  332.  
  333.         case GETRGNMESSAGE:
  334.             rgn      = NewRgn();
  335.             accumRgn = (RgnHandle)data;
  336.             if (accumRgn)
  337.                 if (GetHandleSize((Handle)accumRgn) > 10000)
  338.                     return((long)rgn);
  339.             rct = mDerefCommon(hndl)->rect;
  340.             RectRgn(rgn, &rct);
  341.             if (accumRgn)
  342.                 UnionRgn(rgn, accumRgn, accumRgn);
  343.             return((long)rgn);
  344.             break;
  345.  
  346.         case GETOBJRECTMESSAGE:
  347.         case GETBBOXMESSAGE:
  348.             rptr  = (Rect *)data;
  349.             *rptr = mDerefCommon(hndl)->rect;
  350.             break;
  351.  
  352.         case SETOBJRECTMESSAGE:
  353.             rptr = (Rect *)data;
  354.             mDerefCommon(hndl)->rect = *rptr;
  355.             break;
  356.  
  357.         case SECTOBJRECTMESSAGE:
  358.             rptr = (Rect *)data;
  359.             SectRect(rptr, &(mDerefCommon(hndl)->rect), &rct);
  360.             if (!EmptyRect(&rct)) return(true);
  361.             break;
  362.  
  363.         case DRAWMESSAGE:
  364.             rct = mDerefCommon(hndl)->rect;
  365.             h   = mDerefCommon(hndl)->penHeight;
  366.             w   = mDerefCommon(hndl)->penWidth;
  367.             PenSize(w, h);
  368.             switch (data) {
  369.                 case DRAWOBJ:
  370.                     if (gQDVersion)
  371.                         GetForeColor(&rgb);
  372.                     ForeColor(whiteColor);
  373.                     if (gQDVersion) {
  374.                         rgb2 = mDerefRect(hndl)->contentColor;
  375.                         RGBForeColor(&rgb2);
  376.                     }
  377.                     PaintRect(&rct);
  378.                     ForeColor(blackColor);
  379.                     if (gQDVersion) {
  380.                         rgb2 = mDerefRect(hndl)->borderColor;
  381.                         RGBForeColor(&rgb2);
  382.                     }
  383.                     FrameRect(&rct);
  384.                     if (gQDVersion)
  385.                         RGBForeColor(&rgb);
  386.                     break;
  387.                 case ERASEOBJ:
  388.                     EraseRect(&rct);
  389.                     break;
  390.                 case DRAWSELECT:
  391.                     if (mDerefCommon(hndl)->selected) {
  392.                         for (h = v = 1; (h > -1); h -= (v ^= 1)) {
  393.                             grabber.top  = v ? rct.top  : rct.bottom;
  394.                             grabber.left = h ? rct.left : rct.right;
  395.                             grabber.bottom = (grabber.top  -= 3) + 6;
  396.                             grabber.right  = (grabber.left -= 3) + 6;
  397.                             InvertRect(&grabber);
  398.                         }
  399.                     }
  400.                     break;
  401.                 case DRAWGHOST:
  402.                     PenMode(patXor);
  403.                     FrameRect(&rct);
  404.                     break;
  405.                 case DRAWMASK:
  406.                     FillRect(&rct, (ConstPatternParam)&qd.black);
  407.                     break;
  408.             }
  409.             PenNormal();
  410.             break;
  411.  
  412.         case PRINTMESSAGE:
  413.             DoTreeObjMethod(hndl, DRAWMESSAGE, DRAWOBJ);
  414.             break;
  415.  
  416. #if VH_VERSION
  417.         case VHMESSAGE:
  418.             cptr = ((VHFormatDataPtr)data)->data;
  419.             ccatchr(cptr, 13, 2);
  420.             ccat   (cptr, "$10: TRectObj:");
  421.             ccatchr(cptr, 13, 1);
  422.             ccat   (cptr, "  $00: selected     = ");
  423.             ccatdec(cptr, mDerefRect(hndl)->selected);
  424.             ccatchr(cptr, 13, 1);
  425.  
  426.             rct = mDerefRect(hndl)->rect;
  427.             ccat      (cptr, "  $02: rect         = ($");
  428.             ccatpadhex(cptr, 0, 4, 4, rct.top);
  429.             ccat      (cptr, ",$");
  430.             ccatpadhex(cptr, 0, 4, 4, rct.left);
  431.             ccat      (cptr, ",$");
  432.             ccatpadhex(cptr, 0, 4, 4, rct.bottom);
  433.             ccat      (cptr, ",$");
  434.             ccatpadhex(cptr, 0, 4, 4, rct.right);
  435.             ccat      (cptr, ")");
  436.             ccatchr   (cptr, 13, 1);
  437.             ccat      (cptr, "  $0A: penHeight    = ");
  438.             ccatdec   (cptr, mDerefRect(hndl)->penHeight);
  439.             ccatchr   (cptr, 13, 1);
  440.             ccat      (cptr, "  $0C: penWidth    = ");
  441.             ccatdec   (cptr, mDerefRect(hndl)->penWidth);
  442.             ccatchr   (cptr, 13, 1);
  443.             ccat      (cptr, "  $0E: borderColor  = ($");
  444.             ccatpadhex(cptr, 0, 4, 4, mDerefRect(hndl)->borderColor.red);
  445.             ccat      (cptr, ",$");
  446.             ccatpadhex(cptr, 0, 4, 4, mDerefRect(hndl)->borderColor.green);
  447.             ccat      (cptr, ",$");
  448.             ccatpadhex(cptr, 0, 4, 4, mDerefRect(hndl)->borderColor.blue);
  449.             ccat      (cptr, ")");
  450.             ccatchr   (cptr, 13, 1);
  451.             ccat      (cptr, "  $1$: content      = ($");
  452.             ccatdec   (cptr, mDerefRect(hndl)->content);
  453.             ccatchr   (cptr, 13, 1);
  454.             ccat      (cptr, "  $16: contentColor = ($");
  455.             ccatpadhex(cptr, 0, 4, 4, mDerefRect(hndl)->contentColor.red);
  456.             ccat      (cptr, ",$");
  457.             ccatpadhex(cptr, 0, 4, 4, mDerefRect(hndl)->contentColor.green);
  458.             ccat      (cptr, ",$");
  459.             ccatpadhex(cptr, 0, 4, 4, mDerefRect(hndl)->contentColor.blue);
  460.             ccat      (cptr, ")");
  461.             return(true);
  462.             break;
  463. #endif
  464.  
  465.         case COMPAREMESSAGE:
  466.             return(DefaultEqualTreeObjData(hndl, (TreeObjHndl)data));
  467.             break;
  468.  
  469. /* End of standard messages.  Start of object-specific messages. */
  470.  
  471.         case CLICKMESSAGE:
  472.             click = (ClickInfo *)data;
  473.             switch (click->message) {
  474.                 case CLICKSELECT:
  475.                     for (shndl = hndl; (*(root = (*shndl)->parent))->type != ROOTOBJ; shndl = root) {};
  476.                     selected = mDerefCommon(shndl)->selected;
  477.                     if ((!selected) || (click->localEvent.modifiers & shiftKey)) {
  478.                         if (shndl == hndl)
  479.                             DoTreeObjMethod(hndl, SETSELECTMESSAGE, SELECTTOGGLE);
  480.                                 /* If the object doesn't belong to a group, then we want to change
  481.                                 ** the select status.  If it belongs to a group, the group object
  482.                                 ** is responsible for maintaining the select status. */
  483.                     }
  484.                     break;
  485.                 case CLICKDRAG:
  486.                     OffsetRect(&(mDerefCommon(hndl)->rect), click->offset.h, click->offset.v);
  487.                     break;
  488.             }
  489.             break;
  490.  
  491.         case KEYMESSAGE:
  492.             break;
  493.  
  494.         case SETSELECTMESSAGE:
  495.             noDraw = (data & SELECTNODRAW);
  496.             data  ^= noDraw;
  497.  
  498.             selected = mDerefCommon(hndl)->selected;
  499.             if (selected != data) {        /* The select status is other than desired. */
  500.                 if (!noDraw) {
  501.                     mDerefCommon(hndl)->selected = true;
  502.                     DoTreeObjMethod(hndl, DRAWMESSAGE, DRAWSELECT);
  503.                         /* Force a draw-toggle of the selection grabbers. */
  504.                 }
  505.                 mDerefCommon(hndl)->selected = (selected ^= true);
  506.                 root = GetRootHndl(hndl);
  507.                 if (selected)
  508.                     mDerefRoot(root)->numSelected++;
  509.                 else
  510.                     mDerefRoot(root)->numSelected--;
  511.                         /* Change the global numSelected value to reflect the new
  512.                         ** number of selected objects. */
  513.             }
  514.             break;
  515.  
  516.         case GETSELECTMESSAGE:
  517.             return(mDerefCommon(hndl)->selected);
  518.             break;
  519.  
  520.         case SIZEMESSAGE:
  521.             DoTreeObjMethod(hndl, GETOBJRECTMESSAGE, (long)&oldRct);
  522.             click    = (ClickInfo *)data;
  523.             begMouse = click->localEvent.where;
  524.             GetMouse(&curMouse);
  525.             curMouse.h += click->offset.h;
  526.             curMouse.v += click->offset.v;
  527.             dx1 = dx2 = (curMouse.h - begMouse.h);
  528.             dy1 = dy2 = (curMouse.v - begMouse.v);
  529.             if (dx2 < 0)
  530.                 dx2 = -dx2;
  531.             if (dy2 < 0)
  532.                 dy2 = -dy2;
  533.             OSEventAvail(nullEvent, &option);
  534.             if ((*hndl)->type == EXTSELECTOBJ) option.modifiers = 0;
  535.             if (option.modifiers & shiftKey) {
  536.                 if (dx2 > dy2)
  537.                     dx2 = dy2;
  538.                 else
  539.                     dy2 = dx2;
  540.             }
  541.             if (dx1 < 0)
  542.                 dx2 = -dx2;
  543.             if (dy1 < 0)
  544.                 dy2 = -dy2;
  545.             curMouse.h = begMouse.h + dx2;
  546.             curMouse.v = begMouse.v + dy2;
  547.             fv = (curMouse.v < begMouse.v) ? VFLIPOBJ : 0x00;
  548.             fh = (curMouse.h < begMouse.h) ? HFLIPOBJ : 0x00;
  549.             rct.top    = (fv) ? curMouse.v : begMouse.v;
  550.             rct.bottom = (fv) ? begMouse.v : curMouse.v;
  551.             rct.left   = (fh) ? curMouse.h : begMouse.h;
  552.             rct.right  = (fh) ? begMouse.h : curMouse.h;
  553.             mDerefCommon(hndl)->rect = rct;
  554.             click->oldFlip = click->newFlip;
  555.             click->newFlip = (fv | fh);
  556.             return(!EqualRect(&rct, &oldRct));
  557.             break;
  558.  
  559.     }
  560.  
  561.     return(noErr);
  562. }
  563.  
  564.  
  565.  
  566.